package dao

import (
	"context"
	"wxpay/internal/model"
	"wxpay/pkg/merrors"

	"github.com/nsqio/go-nsq"
	"gorm.io/gorm"
)

type ProfitShare interface {
	Create(ctx context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error)
	QueryByOutOrderNo(ctx context.Context, db *gorm.DB, outOrderNo string) (order *model.Profitshare, err error)
	QueryByTrans(ctx context.Context, db *gorm.DB, txID string) (orders []model.Profitshare, err error)
	SyncSuccess(ctx context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error)
	SyncFailed(ctx context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error)
	SyncProcessing(ctx context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error)
}

type ProfitShareRepo struct {
	*gorm.DB
	producer *nsq.Producer
}

func NewProfitShareRepo(db *gorm.DB, p *nsq.Producer) *ProfitShareRepo {
	return &ProfitShareRepo{
		DB:       db,
		producer: p,
	}
}

// 创建分账记录
func (p ProfitShareRepo) Create(_ context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error) {
	const op merrors.Op = "ProfitShareRepo.Create"
	if e := tx.Create(pfs).Error; e != nil {
		return merrors.E(op, merrors.DBError, e, merrors.ErrInternal)
	}
	return nil
}

// 根据分账单号查询分账记录
func (p ProfitShareRepo) QueryByOutOrderNo(_ context.Context, db *gorm.DB, outOrderNo string) (order *model.Profitshare, err error) {
	const op merrors.Op = "ProfitShareRepo.QueryByOutOrderNo"
	res := model.Profitshare{}
	if err = db.Model(&model.Profitshare{}).Where("out_order_no = ?", outOrderNo).First(&res).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, merrors.E(op, merrors.NotExist, merrors.ErrNotFound, err)
		} else {
			return nil, merrors.E(op, merrors.DBError, merrors.ErrInternal, err)
		}
	}
	order = &res
	return
}

// 更新到分账完成
func (p ProfitShareRepo) SyncSuccess(_ context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error) {
	const op merrors.Op = "ProfitShareRepo.SyncSuccess"
	if e := tx.Model(pfs).Updates(map[string]interface{}{
		"status":        pfs.Status,
		"finish_amount": pfs.FinishAmount,
		"update_time":   pfs.UpdateTime,
	}).Where("id = ?", pfs.ID).Error; e != nil {
		err = merrors.E(op, merrors.DBError, e, merrors.ErrInternal)
		return
	}
	return
}

// 更新到分账失败
func (p ProfitShareRepo) SyncFailed(_ context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error) {
	const op merrors.Op = "ProfitShareRepo.SyncFailed"
	if e := tx.Model(pfs).Updates(map[string]interface{}{
		"status":       pfs.Status,
		"close_reason": pfs.CloseReason,
		"update_time":  pfs.UpdateTime,
	}).Where("id = ?", pfs.ID).Error; e != nil {
		err = merrors.E(op, merrors.DBError, e, merrors.ErrInternal)
		return
	}
	return
}

// 更新到分账处理中
func (p ProfitShareRepo) SyncProcessing(_ context.Context, tx *gorm.DB, pfs *model.Profitshare) (err error) {
	const op merrors.Op = "ProfitShareRepo.SyncProcessing"
	if e := tx.Model(pfs).Updates(map[string]interface{}{
		"status":      pfs.Status,
		"update_time": pfs.UpdateTime,
	}).Where("id = ?", pfs.ID).Error; e != nil {
		err = merrors.E(op, merrors.DBError, e, merrors.ErrInternal)
		return
	}
	return
}

func (p ProfitShareRepo) QueryByTrans(_ context.Context, db *gorm.DB, txID string) (orders []model.Profitshare, err error) {
	const op merrors.Op = "ProfitShareRepo.QueryByTrans"
	if e := db.Model(model.Profitshare{}).Where("wx_trans_id = ?", txID).Find(&orders).Error; e != nil {
		err = merrors.E(op, merrors.DBError, e, merrors.ErrInternal)
		return
	}
	return
}
